package cn.dida.controller;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Pattern;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import cn.dida.model.*;
import cn.dida.service.LgsNodeService;
import cn.dida.util.DateUtils;
import cn.dida.util.ExcelUtil;
import cn.dida.util.QRCodeUtil;
import cn.dida.util.ValidUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import cn.dida.exception.BizzException;
import cn.dida.service.LgsBillService;
import cn.dida.service.ProductService;

/**
 * <p>扫码管理</p>
 * @auther lisha
 * @date 2017-2-8 14:45:12
 */
@Controller
public class LgsBillsController extends BaseController{

	@Autowired
	private LgsBillService lgsBillService;
	@Autowired
	private LgsNodeService lgsNodeService;
	@Autowired
	private ProductService productService;

	/**
	 * 获取单号  规则：16位规则：Q+年份（2位）+当天在当年的天数不够三位补零（3位）+ 当天毫秒（8位）+ 随机值（3位）
	 * @return
	 */
	@ResponseBody
	@GetMapping("/getBillsNo")
	public HttpResponseBodyWrapper getBillsNo(){

		String str = "Q";

		Calendar ca = Calendar.getInstance();//创建一个日期实例

		String yearLast = new SimpleDateFormat("yy",Locale.CHINESE).format(ca.getTime());
		str += yearLast;

		ca.setTime(new Date());//实例化一个日期
		String yearDay =ca.get(Calendar.DAY_OF_YEAR)+"";//获取是第多少天
		for(int i=0; i<3-yearDay.length();i++){
			str += 0;
		}
		str += yearDay;

		//获取当天0点时间
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.HOUR, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.MILLISECOND, 0);

		String millis=(ca.getTimeInMillis()-cal.getTimeInMillis()) +"";
		for(int i=0; i<8-millis.length();i++){
			str += 0;
		}
		str += millis;
		for(int i=0; i<3;i++){
			str += new Random().nextInt(10);
		}
		return new HttpResponseBodyWrapper(str);
	}

	@ResponseBody
	@GetMapping("/getCustSearchList")
	public List<LgsCust> getCustSearchList(HttpServletRequest request, String name_code, Integer limit)
			throws Exception {
		UserSession userSession = getUserSession(request);

		if (name_code == null || "".equals(name_code.trim())) {
			return null;
		}
		if (limit == null || limit <= 0 || limit > 30) {
			limit = 10;
		}
		List<LgsCust> custList = lgsBillService.getCustSearchList(name_code.trim(), limit,
				userSession.getCompanyId());
		return custList;
	}
	
	/**
	 * 创建单据
	 * @param request
	 * @return HttpResponseBodyWrapper 封装操作标记（ true新增成功，false新增失败）
	 * @throws Exception
	 */
	@ResponseBody
    @PostMapping("/lgsBills")
    public HttpResponseBodyWrapper add(HttpServletRequest request, @RequestBody LgsBills lgsBills) throws Exception {

		if(!Pattern.matches(ValidUtil.PWS_PATTERN,lgsBills.getBillsNo())){
			throw new BizzException(BizzException.error_code_invalid_params, "请输入数字、字母组成的单据号！");
		}
        UserSession userSession = getUserSession(request);
        lgsBills.setCompanyId(userSession.getCompanyId());
        lgsBills.setcAdmin(userSession.getAccount());

        Boolean flag = lgsBillService.isExistsBillNo(userSession.getCompanyId(), lgsBills.getBillsNo(),1);
        if(flag){
        	throw new BizzException(BizzException.error_code_invalid_params, "已存在【"+lgsBills.getBillsNo()+"】的单据");
        }

        lgsBills.setBillsNo(StringUtils.trimToNull(lgsBills.getBillsNo()));
        Boolean result = lgsBillService.insertLgsBills(lgsBills);
        return new HttpResponseBodyWrapper(result);
    }
	
	/**
	 * 单据列表
	 * @param productName 产品名称
	 * @param billsNo 单据号
	 * @param billsType 单据类型
	 * @param node 节点
	 * @param nubsS 应扫数量（小）
	 * @param nubsE 应扫数量（大）
	 * @param fromId 发货地点
	 * @param toId 收货地点
	 * @param depotScan 扫描地点
	 * @param cTimeS 操作时间（开始）
	 * @param cTimeE 操作时间 （结束）
	 * @param sta 状态，1初始创建，2使用中，3完成，4封存
	 * @param page 分页游标
	 * @return ModelAndView 节点管理列表页面
	 * @throws Exception
	 * @date 2017-2-9 14:31
	 */
	@GetMapping("/lgsBills")
    public ModelAndView list(HttpServletRequest request, String productName, String billsNo, Integer billsType, Integer node, Integer nubsS, Integer nubsE,
			Integer scanNubsS, Integer scanNubsE,Integer fromId, Integer toId,Integer depotScan, String cTimeS, String cTimeE, Integer sta, Integer page) throws Exception {
        Map<String, Object> model = new HashMap<String, Object>();
        UserSession userSession = getUserSession(request);
        page = (page == null || page < 1) ? 1 : page;
        
        productName = StringUtils.trimToEmpty(productName);
        billsNo = StringUtils.trimToEmpty(billsNo);
        
        Pageable<LgsBills> lgsBillsList = lgsBillService.query(userSession.getCompanyId(), productName, billsNo, billsType, node,
        		nubsS, nubsE, scanNubsS, scanNubsE, fromId, toId, depotScan,cTimeS, cTimeE, sta, page);

        model.put("lgsBillsList", lgsBillsList);
        model.put("productName", productName);
        model.put("billsNo", billsNo);
        model.put("billsType", billsType);
        model.put("node", node);
        model.put("nubsS", nubsS);
        model.put("nubsE", nubsE);
		model.put("scanNubsS", scanNubsS);
		model.put("scanNubsE", scanNubsE);
        model.put("fromId", fromId);
        model.put("toId", toId);
        model.put("cTimeS", cTimeS);
        model.put("cTimeE", cTimeE);
        model.put("sta", sta);
		model.put("depotScan", depotScan);
        
        return new ModelAndView("lgsBills_list").addAllObjects(model);
    }

	/**
	 * 数据导出
	 * @param productName
	 * @param billsNo
	 * @param billsType
	 * @param node
	 * @param nubsS
	 * @param nubsE
	 * @param from
	 * @param to
	 * @param depotScan
	 * @param cTimeS
	 * @param cTimeE
	 * @param sta
	 * @return
	 */
	@GetMapping("/lgsBills/export")
	public String queryForExport (HttpServletRequest request, HttpServletResponse response,  String productName,
								  String billsNo, Integer billsType, Integer node, Integer nubsS, Integer nubsE,Integer scanNubsS, Integer scanNubsE,
								  Integer from, Integer to, Integer depotScan, String cTimeS, String cTimeE, Integer sta)throws IOException{

		UserSession userSession = getUserSession(request);
		List<LgsBills> exportList = lgsBillService.queryForExport(userSession.getCompanyId(), productName, billsNo, billsType, node,
				scanNubsS,scanNubsE,nubsS, nubsE, from, to,depotScan, cTimeS, cTimeE, sta);
		String fileName = "单据数据导出" + DateUtils.dateToString(Calendar.getInstance().getTime(), "yyyy-MM-dd");

		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>(exportList.size());
		Map<String, Object> fmap = null;
		for(LgsBills bill : exportList){
			fmap=new HashMap<String, Object>();
			Long tid = NumberUtils.toLong(bill.getId().toString(), 0L);
			String proNames=""; String nubs =""; String ScanNubs = "";
			List<LgsBillsProduct> proList = bill.getBillsProductList();
			for(int i=0; i<proList.size();i++){
				proNames += proList.get(i).getProductName();
				nubs += proList.get(i).getNubs() == null ? "" : proList.get(i).getNubs();
				ScanNubs +=proList.get(i).getScanNubs() == null ? "" : proList.get(i).getScanNubs();
				if(i+1<proList.size()){
					proNames += "\r\n";
					nubs += "\r\n";
					ScanNubs += "\r\n";
				}
			}
			fmap.put("id", tid);
			fmap.put("billsNo", bill.getBillsNo());
			fmap.put("proNames", proNames);
			fmap.put("nodeName", bill.getNodeName());
			Integer type = bill.getType();
			if(type ==1){
				fmap.put("type", "自建");
			}else if(type == 2){
				fmap.put("type", "erp抓取");
			}else{
				fmap.put("type", "其它");
			}
			fmap.put("nubs", nubs);
			fmap.put("ScanNubs", ScanNubs);
			fmap.put("depotScanName", bill.getDepotScanName());
			fmap.put("to", bill.getTo());
			fmap.put("from", bill.getFrom());

			String time = DateUtils.formatTimeInMillis((Long)bill.getcTime());
			fmap.put("cTime", time);

			Integer state =bill.getSta();//状态，1初始创建，2使用中，3完成，4封存,5已作废
			if(state == 1){
				fmap.put("sta", "初始创建");
			}else if(state == 2){
				fmap.put("sta", "使用中");
			}else if(state == 3){
				fmap.put("sta", "已完成");
			}else if(state == 4){
				fmap.put("sta", "封存");
			}else if(state == 5){
				fmap.put("sta", "已作废");
			}else {
				fmap.put("sta", "异常");
			}

			list.add(fmap);
		}

		String columnNames[] = {"ID","单号","产品名称","操作类型","单据类型","应扫瓶数","实扫瓶数","扫码地点","收货对象","发货对象","操作时间","状态"};//列名
		String keys[] = {"id","billsNo","proNames","nodeName","type","nubs","ScanNubs","depotScanName","to","from","cTime","sta"};//map中的key
		ByteArrayOutputStream os = new ByteArrayOutputStream();
		try {
			ExcelUtil.createWorkBook(list, keys, columnNames).write(os);
		} catch (IOException e) {
			e.printStackTrace();
		}
		byte[] content = os.toByteArray();
		InputStream is = new ByteArrayInputStream(content);
		// 设置response参数，可以打开下载页面
		response.reset();
		response.setContentType("application/vnd.ms-excel;charset=utf-8");
		response.setHeader("Content-Disposition", "attachment;filename=" + new String((fileName + ".xls").getBytes(), "iso-8859-1"));
		ServletOutputStream out = response.getOutputStream();
		BufferedInputStream bis = null;
		BufferedOutputStream bos = null;
		try {
			bis = new BufferedInputStream(is);
			bos = new BufferedOutputStream(out);
			byte[] buff = new byte[2048];
			int bytesRead;
			// Simple read/write loop.
			while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
				bos.write(buff, 0, bytesRead);
				bos.flush();
			}
		} catch (final IOException e) {
			throw e;
		} finally {
			if (bis != null)
				bis.close();
			if (bos != null)
				bos.close();
		}
		return null;
	}


	/**
	 * 获取单据详情
	 * @param request
	 * @param id 节点id
	 * @return HttpResponseBodyWrapper 封装单个节点管理实体数据
	 * @throws Exception
	 */
	@ResponseBody
    @GetMapping("/lgsBills/{id}")
    public HttpResponseBodyWrapper getBills(HttpServletRequest request, @PathVariable int id) throws Exception {
		UserSession userSession = getUserSession(request);
		LgsBills bill = lgsBillService.getLgsBillById(id, userSession.getCompanyId());
        return new HttpResponseBodyWrapper(bill);
    }
	
	/**
	 * 作废单据
	 * @param 
	 * @param 
	 * @param 
	 * @return HttpResponseBodyWrapper
	 * */
	@ResponseBody
	@PostMapping("/lgsBills/invalid")
    public HttpResponseBodyWrapper billInvalid(HttpServletRequest request, int id) throws Exception {
		UserSession userSession = getUserSession(request);
        Boolean result = lgsBillService.billInvalid(userSession.getCompanyId(), id);
        
        return new HttpResponseBodyWrapper(result);
    }
	
	/**
	 * 打开新建单据页面
	 * @param request
	 * @param session
	 * @return
	 * @throws Exception
	 */
	@GetMapping("/lgsBills/add")
    public ModelAndView add(HttpServletRequest request, HttpSession session) throws Exception {
		UserSession userSession = getUserSession(request);
        Map<String, Object> model = new HashMap<String, Object>();
        
        Pageable<Product> productList = productService.queryProduct(userSession.getCompanyId(), "", 1, 1);
        model.put("productList", productList);

        List<LgsNode> nodeList = lgsNodeService.getNodeList(userSession.getCompanyId(), 1);
		model.put("nodeList", nodeList);

		//是否有选择其他公司产品的权限
		Integer isBridgeCompany = 0;
		String resIds = userSession.getResIds();
		String[] res=resIds.split(",");
		List<String> resIdList = new ArrayList<String>();
		resIdList= Arrays.asList(res);
		if(resIdList.contains("1011")==true)
		{
			isBridgeCompany=1;
		}
		model.put("isBridgeCompany", isBridgeCompany);

        return new ModelAndView("lgsBills_new").addAllObjects(model);
	}
	
	/**
	 * 查看单据
	 * @param billId 单据id
	 * @return ModelAndView
	 * */
	@GetMapping("/lgsBills/getBillDetail")
    public ModelAndView getBillDetail(HttpServletRequest request, String billId) throws Exception {
        Map<String, Object> model = new HashMap<String, Object>();
        UserSession userSession = getUserSession(request);
        LgsBills bill = lgsBillService.getLgsBillById(Integer.valueOf(billId), userSession.getCompanyId());
        model.put("bill", bill);
        
        List<LgsBillsProduct> selectedProductList = lgsBillService.getProductByBillId(Integer.valueOf(billId));
        model.put("selectedProductList", selectedProductList);
	    
		return new ModelAndView("lgsBills_detail").addAllObjects(model);
    }
	/**
	 * 打印单据
	 * @param billId 单据id
	 * @return ModelAndView
	 * */
	@GetMapping("/lgsBills/printBill")
	public ModelAndView printBilletail(HttpServletRequest request, String billId) throws Exception {
		Map<String, Object> model = new HashMap<String, Object>();
		UserSession userSession = getUserSession(request);
		LgsBills bill = lgsBillService.getLgsBillById(Integer.valueOf(billId), userSession.getCompanyId());
		model.put("bill", bill);
		
		List<LgsBillsProduct> selectedProductList = lgsBillService.getProductByBillId(Integer.valueOf(billId));
		model.put("selectedProductList", selectedProductList);
		
		LgsBillsProduct total = lgsBillService.getTotalNubsByBillId(Integer.valueOf(billId));
		model.put("total", total);
		return new ModelAndView("lgsBills_print").addAllObjects(model);
	}

	@GetMapping("/getBillsQrImage/{billsNo}")
	@ResponseBody
	public void getBillsQrImage(HttpServletRequest request,HttpServletResponse response,@PathVariable String billsNo){

		UserSession userSession = getUserSession(request);
		String companyErpCode = lgsBillService.getComanyErpCode(userSession.getCompanyId());
		String str = "https://lgs.vats.com.cn/scan/9/"+billsNo + "/" + companyErpCode;
		QRCodeUtil.createQrcode(str, response);
	}


	/**
	 * 打开单据编辑页面
	 * @param billId 单据id
	 * @return ModelAndView
	 * */
	@GetMapping("/lgsBills/openUpdateBill")
	public ModelAndView openUpdateBill(HttpServletRequest request, String billId) throws Exception {
		Map<String, Object> model = new HashMap<String, Object>();
		UserSession userSession = getUserSession(request);
		LgsBills bill = lgsBillService.getLgsBillById(Integer.valueOf(billId), userSession.getCompanyId());
		model.put("bill", bill);
		Pageable<Product> productList = productService.queryProduct(userSession.getCompanyId(), "", 1, 1);
        model.put("productList", productList);
		List<LgsNode> nodeList = lgsNodeService.getNodeList(userSession.getCompanyId(), 1);
		model.put("nodeList", nodeList);

		//是否有选择其他公司产品的权限
		Integer isBridgeCompany = 0;
		String resIds = userSession.getResIds();
		String[] res=resIds.split(",");
		List<String> resIdList = new ArrayList<String>();
		resIdList= Arrays.asList(res);
		if(resIdList.contains("1011")==true)
		{
			isBridgeCompany=1;
		}
		model.put("isBridgeCompany", isBridgeCompany);

		return new ModelAndView("lgsBills_edit").addAllObjects(model);
	}

	/**
	 * 获取单据关联产品
	 * @param request
	 * @param billId
	 * @return
	 * @throws Exception
	 */
	@ResponseBody
	@GetMapping("/lgsBills/selectedProductList/{billId}")
	public HttpResponseBodyWrapper selectedProductList(HttpServletRequest request, @PathVariable Integer billId) throws Exception {
		List<LgsBillsProduct> selectedProductList = lgsBillService.getProductByBillId(billId);

		return new HttpResponseBodyWrapper(selectedProductList);


	}
	
	/**
	 * 修改单据
	 * @param request
	 * @return HttpResponseBodyWrapper 封装操作标记（ true更新成功，false更新失败）
	 * @throws Exception
	 */
	@ResponseBody
    @PutMapping("/lgsBills/edit")
    public HttpResponseBodyWrapper updateBill(HttpServletRequest request, @RequestBody LgsBills lgsBills) throws Exception {

		if(!Pattern.matches(ValidUtil.PWS_PATTERN,lgsBills.getBillsNo())){
			throw new BizzException(BizzException.error_code_invalid_params, "请输入数字、字母组成的单据号！");
		}
        UserSession userSession = getUserSession(request);
        Integer companyId = userSession.getCompanyId();
        lgsBills.setCompanyId(userSession.getCompanyId());
        lgsBills.setcAdmin(userSession.getAccount());

        LgsBills bill_temp = lgsBillService.getLgsBillById(lgsBills.getId(), companyId);
        if(bill_temp != null && !(bill_temp.getBillsNo().equals(lgsBills.getBillsNo()))){
        	if(lgsBillService.isExistsBillNo(companyId, lgsBills.getBillsNo(),1)){
        		throw new BizzException(BizzException.error_code_invalid_params, "已存在【"+lgsBills.getBillsNo()+"】的单据");
        	}
        }

        lgsBills.setBillsNo(StringUtils.trimToNull(lgsBills.getBillsNo()));
        Boolean result = lgsBillService.updateBills(lgsBills);
        return new HttpResponseBodyWrapper(result);

        
    }
	
	/**
     * 选择商品 关键字查询
     * @param keyword 查询条件
     * @param page 分页游标
     * @return HttpResponseBodyWrapper
     * */
    @PostMapping("/lgsBills/getProductList")
    @ResponseBody
    public HttpResponseBodyWrapper getProductList(HttpServletRequest request, String keyword, Integer page) throws Exception {

        UserSession userSession = getUserSession(request);
		page = (page == null || page < 1) ? 1 : page;
        //Pageable<Product> selectedProductList = activityService.querySelected(userSession.getCompanyId(), keyword, 1, page);
		if(keyword != null){
			keyword=keyword.trim();
		}
        Pageable<Product> selectedProductList = productService.queryProduct(userSession.getCompanyId(), keyword, 1, page);
        
        return new HttpResponseBodyWrapper(selectedProductList);
    }

	/**
	 * 根据编码获取产品信息
	 * @param request
	 * @param keyword
	 * @return
	 * @throws Exception
	 */
	@PostMapping("/lgsBills/getProductByNumber")
	@ResponseBody
	public HttpResponseBodyWrapper getProductByNumber(HttpServletRequest request, String keyword) throws Exception {

		if(keyword != null){
			keyword=keyword.trim();
		}
		List<Product> productList = productService.getByNumber(keyword);

		Pageable<Product> selectedProductList = new Pageable<>(1, 1, 1, productList);

		return new HttpResponseBodyWrapper(selectedProductList);
	}

    /**
     * 地点列表 （扫描地点）
     * @param request
     * @param state 状态（1：正常、0：已停用）
     * @param 
     * @return 
     * @throws Exception
     */
    @ResponseBody
    @GetMapping(value = "/lgsBills/allDepotList", produces = MediaType.APPLICATION_JSON_VALUE)
    public HttpResponseBodyWrapper getDepot(HttpServletRequest request, Integer state) throws Exception {

    	UserSession userSession = getUserSession(request);
    	List<LgsDepot> depotList = lgsBillService.getDepotList(userSession.getCompanyId(), state);
    	return new HttpResponseBodyWrapper(depotList);
    }

	/**
	 * 获取同一公司下状态正常的 客户对象（收发货对象用）
	 * @param request
	 * @param state
	 * @return
	 */
	@ResponseBody
	@GetMapping(value = "/lgsBills/getCustList", produces = MediaType.APPLICATION_JSON_VALUE)
	public HttpResponseBodyWrapper getCustList(HttpServletRequest request, Integer state) throws Exception {

		UserSession userSession = getUserSession(request);
		List<LgsCust> custList = lgsBillService.getCustList(userSession.getCompanyId(), state);

		return new HttpResponseBodyWrapper(custList);
	}



	/**
	 * 获取明细
	 * @param request
	 * @param billId  单据id
	 * @param batchNub 批次号
	 * @param qrcodeBoxId  箱码id
	 * @param qrcodeBottleId 瓶码id
	 * @param page
	 * @return
	 * @throws Exception
	 */
	@GetMapping("/lgsBills/item")
    public ModelAndView itemList(HttpServletRequest request,String billId, String batchNub, String qrcodeBoxId, String qrcodeBottleId, Integer page) throws Exception {
        Map<String, Object> model = new HashMap<String, Object>();
        UserSession userSession = getUserSession(request);
        page = (page == null || page < 1) ? 1 : page;
        
       /* batchNub = StringUtils.trimToEmpty(batchNub);
        qrcodeBoxId = StringUtils.trimToEmpty(qrcodeBoxId);
        qrcodeBottleId = StringUtils.trimToEmpty(qrcodeBottleId);*/
        
        Pageable<LgsLogPdaScan> itemList = lgsBillService.queryBillsDetail(billId,userSession.getCompanyId(), batchNub, qrcodeBoxId, qrcodeBottleId, page);

        model.put("itemList", itemList);
        model.put("batchNub", batchNub);
        model.put("qrcodeBoxId", qrcodeBoxId);
        model.put("qrcodeBottleId", qrcodeBottleId);
        model.put("billId",billId);
        return new ModelAndView("lgsBills_item").addAllObjects(model);
    }
    
}
